
use std::collections::{HashMap as Map};

use common::*;

pub fn run(  n:usize,
             data:&Vec<Instance>,
             uu:&mut Map<u32,Repr>,
             vv:&mut Map<u32,Repr>) -> f64 {

    let g = 0.005;
    let rate = 0.01;

    let mut ss = 0.0;

    for i in data {
        let p = i.p;
        let q = i.q;
        let r = i.r;

        let mut pu = uu.get_mut(&p).unwrap();
        let mut qv = vv.get_mut(&q).unwrap();

        let rr = get_score(n, &pu,&qv);

        let err = r-rr;

        let mut t:Vec<f64> = Vec::new();
        for j in 0..n {
            t.push(qv.v[j]);
        }

        for j in 0..n {
            qv.v[j] += rate*(err*pu.v[j]-g*qv.v[j]);
        }
        for j in 0..n {
            pu.v[j] += rate*(err*t[j]-g*pu.v[j]);
        }
        //qv.b += rate*(err-g*qv.b);
        //pu.b += rate*(err-g*qv.b);
        //println!("{},{}",r,rr);

        ss += err*err;
    }
    let s = data.len() as f64;
    (ss/s).sqrt()
}
